home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / Sherlock 2.0 / Sherlock_DevLib / sl_init.c < prev    next >
Text File  |  1996-04-06  |  10KB  |  492 lines

  1. /*
  2.     Sherlock initialization routines.
  3.  
  4.     source:  sl_init.c
  5.     started: November 4, 1993.
  6.     version:
  7.         February 5, 1996.
  8.             Added support for Symantec C.
  9.         September 26, 1995.
  10.             log_open now takes only one argument.
  11.         January 7, 1994.
  12. */
  13.  
  14. #include <LIBlib.h>
  15.  
  16. #include <sl.h>
  17. #include <sl2.h>
  18.  
  19. #include <LIBenv.h>
  20. #include <LIBlog.h>
  21. #include <LIBmem.h>
  22.  
  23. #if defined(THINK_C) || defined(SYMANTEC_C) || defined(__MWERKS__)
  24.     #include <mac_gui.h>
  25. #endif
  26.  
  27. #include <ctype.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30.  
  31. /*
  32.     Globals initialized by this module...
  33. */
  34.  
  35. /*
  36.     The call stack.
  37. */
  38. sl_snode *    sl_stack    = NULL;        /* Dynamically allocated. */
  39. int            sl_level    = 0;        /* Stack pointer. */
  40. int            sl_lmax        = 0;        /* Max stack pointer. */
  41.  
  42. /*
  43.     The hash table.
  44. */
  45. sl_node ** sl_htab = NULL;
  46.  
  47. /*
  48.     The wildcard list.
  49. */
  50. sl_node * sl_wcard = NULL;             /* Head of wildcard list. */
  51.  
  52. /*
  53.     The "check" name of the current macro.
  54. */
  55. char * sl_cname = NULL;    /* The "check" name of current macro. */
  56.  
  57. /*
  58.     The local and global disable counts.
  59. */
  60. long    sl_ldisable    = 0;      /* Local disable count. */
  61. long    sl_gdisable    = 0;      /* Global disable count. */
  62.  
  63. /*
  64.     Global flags.
  65.  
  66.     sl_troff is TRUE initially to avoid trouble if Sherlock
  67.     macros are called before SL_INIT is called.
  68. */
  69. bool sl_troff        = TRUE;        /* TRUE: all tracing disabled. */
  70. bool sl_nodots        = FALSE;    /* TRUE: no level dots. */
  71. bool sl_warning        = TRUE;        /* TRUE: warn about negative time. */
  72. bool sl_full_trace    = FALSE;    /* TRUE: make STATB the same as TICKB. */
  73.  
  74. long    sl_neg_count    = 0;        /* Number of negative times. */
  75. int        sl_node_count    = 0;        /* Allocated nodes. */
  76.  
  77. #if defined(THINK_C) || defined(SYMANTEC_C) || defined(__MWERKS__)
  78.     UnsignedWide sl_wide_time;
  79. #endif
  80.  
  81.  
  82. /*
  83.     Variables local to this file.
  84. */
  85. static bool        init_flag    = FALSE;    /* Sherlock inited flag. */
  86. static sl_node *node_table = NULL;        /* Dynamically allocated. */
  87. static bool        signon_flag = FALSE;    /* TRUE: the signon message has been printed. */
  88.  
  89. /*
  90.     Function prototypes of internal routines.
  91. */
  92. static int        sl_prefix    (char *, char *);
  93. static void        sl_set          (char *, int);
  94.  
  95. /*
  96.     Enable Sherlock macros initially.
  97. */
  98. void
  99. sl_go(void)
  100. {
  101.     if (!init_flag) {
  102.         sl_troff = FALSE;
  103.         init_flag = TRUE;
  104.     }
  105. }
  106.  
  107. /*
  108.     SL_INIT macro--Initialize the statistics routines.
  109. */
  110. void
  111. sl_init(char * version)
  112. {
  113.     /*
  114.         Allocate Sherlock's tables.
  115.         Nothing bad happens sl_init is called twice.
  116.     */
  117.     if (node_table == NULL) {
  118.  
  119.         node_table    = lib_calloc( (size_t) SL_MAX_NODES, sizeof(sl_node));
  120.         sl_stack    = lib_calloc( (size_t) SL_MAX_STACK, sizeof(sl_snode));
  121.         sl_htab        = lib_calloc( (size_t) SL_MAX_HASH,  sizeof(sl_node *));
  122.  
  123.         if (node_table == NULL || sl_stack == NULL || sl_htab == NULL) {
  124.             sl_abort(SL_ABORT_INIT);
  125.         }
  126.     }
  127.  
  128.     /* Set size of initial stack area. */
  129.     #if 0 // defined(THINK_C) // doesn't work on PowerPc
  130.         sl_min_margin = sl_margin_start = env_stackMargin();
  131.     #endif
  132.  
  133.     /* 7/17/89: indicate that we are starting to initialize. */
  134.     sl_troff = FALSE;
  135.     
  136.     if (strcmp(version, SL_VERSION_NAME) != 0) {
  137.         es("sl_init: Header version "); es(version);
  138.         es(" does not match run-time version: ");
  139.         es(SL_VERSION_NAME); enl();
  140.         sl_exit();
  141.     }
  142.  
  143.      /*
  144.          PC only code:
  145.  
  146.          Initialize the interrupt vectors.  See prf.asm.
  147.      */
  148.      #if defined(TURBOC) || defined(MICRO_SOFT)
  149.         sl_von();
  150.         DEBUG(es("Trap vectors installed.\n"));
  151.     #endif
  152. }
  153.  
  154. /*
  155.     Return TRUE if string s1 matches string s2 with wildcards possible in
  156.     string s1.
  157.  
  158.     The string s2 may start with '-', which inhibits wildcard matches.
  159. */
  160. int
  161. sl_match(register char *s1, register char *s2)
  162. {
  163.     register char c;
  164.  
  165.     /* '-' inhibits wildcard matches. */
  166.     if (*s2 == '-') {
  167.         return FALSE;
  168.     }
  169.  
  170.     for (;;) {
  171.         c = *s1++;
  172.         if (c == '\0') {
  173.             return !*s2;
  174.         }
  175.         else if (c == '*') {
  176.             /* Matches zero or more characters. */
  177.             return TRUE;
  178.         }
  179.         else if (c == '?') {
  180.             /* Matches exactly one character. */
  181.             if (*s2 == '\0') {
  182.                 return FALSE;
  183.             }
  184.             else {
  185.                 s2++;
  186.             }
  187.         }
  188.         else if (c != *s2++) {
  189.             return FALSE;
  190.         }
  191.     }
  192. }
  193.  
  194. /*
  195.     Allocate a new node for tracepoint s from the static node table.
  196.  
  197.     If a match is found from the wildcard list, use that value for tracing.
  198.     Otherwise, set the tracing field to zero (FALSE).
  199. */
  200. sl_node *
  201. sl_new(char *s)
  202. {
  203.     register sl_node * node, *p;
  204.  
  205.     if (node_table == NULL) {
  206.         sl_abort(SL_ABORT_NEW);
  207.     }
  208.  
  209.     /* Not found. Point node at a new node. */
  210.     if (sl_node_count >= SL_MAX_NODES) {
  211.         es("sl_new: trace table overflow\n");
  212.         sl_exit();
  213.     }
  214.  
  215.     /* Create the new node. */
  216.     node = node_table + sl_node_count;
  217.     sl_node_count++;
  218.     node -> name  = s;
  219.     node -> calls = 0;
  220.  
  221.     /*
  222.         Search the wildcard list for a node which matches s.
  223.         If found.  Set trace field.
  224.     */
  225.     for (p = sl_wcard; p; p = p -> next) {
  226.         if (sl_match(p -> name, s)) {
  227.             node -> trace =  (p -> trace) ? ((p -> trace) | SL_WILD_BIT) : 0;
  228.             return node;
  229.         }
  230.     }
  231.  
  232.     /* No match. */
  233.     node -> trace = 0;
  234.     return node;
  235. }
  236.  
  237. /*
  238.     SL_OFF macro.
  239.     Turn tracing off for one variable or a class of variables.
  240. */
  241. void
  242. sl_off(char *s)
  243. {
  244.     if (strcmp(s, "sl_trace")==0) {
  245.         ecnl(); es("Disabling ALL tracing...\n");
  246.         sl_troff = TRUE;
  247.         return;
  248.     }
  249.     if (strcmp(s, "sl_dots")==0) {
  250.         ecnl(); es("Disabling level dots...\n");
  251.         sl_nodots = TRUE;
  252.         return;
  253.     }
  254.     if (strcmp(s, "sl_time")==0) {
  255.         ecnl(); es("Disabling time reporting...\n");
  256.         sl_time_flag = FALSE;
  257.         return;
  258.     }
  259.     if (strcmp(s, "sl_warning")==0) {
  260.         ecnl(); es("Disabling negative time warning...\n");
  261.         sl_warning = FALSE;
  262.         return;
  263.     }
  264.     
  265.     if (!signon_flag) {
  266.         sl_signon();
  267.     }
  268.     es("Disabling trace of "); es(s); enl();
  269.  
  270.     sl_cname = "TRACE_OFF";
  271.     sl_set(s, 0);
  272. }
  273.  
  274. /*
  275.     SL_ON macro.
  276.     Turn tracing on for one variable or a class of variables.
  277. */
  278. void
  279. sl_on(char *s)
  280. {
  281.      /* BUG FIX to V1.5 */
  282.      if (sl_troff && sl_match(s, "trace")) {
  283.         es("Revoking --trace...\n");
  284.         es("WARNING: this may generate call stack underflows.\n");
  285.         sl_troff = FALSE;
  286.         return;
  287.     }
  288.     if (strcmp(s, "sl_full_trace")==0) {
  289.         ecnl(); es("Tracing statb macros...\n");
  290.         sl_full_trace = TRUE;
  291.         return;
  292.     }
  293.  
  294.     /*
  295.         ++>>file_name opens file_name.
  296.  
  297.         We want to sign on just *after* the ++>> arg opening the log file,
  298.         and we will assume the ++>> arg is the first arg.
  299.     */
  300.  
  301.     if (*s == '>' && *(s+1) == '>') {
  302.     
  303.         /* 9/26/95: log_open now takes only one argument. */
  304.         log_open(s+2);
  305.         if (!signon_flag) {
  306.             sl_signon();
  307.         }
  308.     }
  309.     else {
  310.         if (!signon_flag) {
  311.             sl_signon();
  312.         }
  313.         es("Enabling  trace of "); es(s); enl();
  314.     
  315.         sl_cname = "TRACE_ON";
  316.         sl_set(s, 1);
  317.     }
  318. }
  319.  
  320. /*
  321.     SL_PARSE macro--Parse the command list.
  322.     argcp points to the argc count.
  323.     argv contains pointers to the arguments.
  324.     on_str and off_str are the on_prefix and off_prefix respectively.
  325. */
  326. void
  327. sl_parse(argcp, argv, on_str, off_str)
  328. int *argcp; char **argv; char *on_str; char *off_str;
  329. {
  330.     char ** base;
  331.     char * arg;
  332.     int argc;
  333.     size_t on_len, off_len;
  334.  
  335.     on_len  = strlen(on_str);
  336.     off_len = strlen(off_str);
  337.  
  338.     argc = *argcp;
  339.     argc--;
  340.     argv++;
  341.     base = argv;
  342.     while (argc-- > 0) {
  343.         arg = *argv++;
  344.  
  345.         /* 8/8/89: Protect against over-run user error. */
  346.         if (arg == 0L) {
  347.             es("Warning: argc argument to SL_PARSE too big\n");
  348.             return;
  349.         }
  350.  
  351.         if (sl_prefix(on_str, arg)) {
  352.             if (!*(arg + on_len)) {
  353.                 es("Warning: lone "); es(on_str); enl();
  354.                 sl_exit();
  355.             }
  356.             sl_on(arg + on_len);
  357.  
  358.             /* One less argument for the program. */
  359.             (*argcp)--;
  360.         }
  361.         else if (sl_prefix(off_str, arg)) {
  362.             if (!*(arg + off_len)) {
  363.                 es("Warning: lone "); es(off_str); enl();
  364.                 sl_exit();
  365.             }
  366.             sl_off(arg + off_len);
  367.  
  368.             /* One less argument for the program. */
  369.             (*argcp)--;
  370.  
  371.         }
  372.         else {
  373.             /* Compact original argv vector. */
  374.             *base++ = arg;
  375.         }
  376.     }
  377.  
  378.     /* 2/25/92 */
  379.     *base++ = NULL;
  380.     if (!signon_flag) {
  381.         sl_signon();
  382.     }
  383.     ecnl();
  384. }
  385.  
  386. /*
  387.     Return TRUE if string p is a prefix of string s.
  388. */
  389. static int
  390. sl_prefix(char *p, char *s)
  391. {
  392.     while (*p) {
  393.         if (*p++ != *s++) {
  394.             return FALSE;
  395.         }
  396.     }
  397.     return TRUE;
  398. }
  399.  
  400. /*
  401.     Update the tracing status for string s and set the disable flags.
  402.     Enable tracing if flag is TRUE.
  403.  
  404.     If s contains a wildcard, ALL nodes matching s have their enable
  405.     field set to flag and a new entry for s is added to the wild card list.
  406.     Otherwise, the single node (if it exists) which matches s has its
  407.     enable field set to flag.
  408. */
  409. static void
  410. sl_set(char *s, int flag)
  411. {
  412.     sl_node * p = NULL;
  413.  
  414.     /* Be very careful. */
  415.     if (sl_htab == NULL) {
  416.         return;
  417.     }
  418.  
  419.     sl_check(s);
  420.     if (!sl_wild(s)) {
  421.  
  422.         /* No wild card.  Just set one flag. */
  423.         p = sl_find("SL_ON, SL_OFF or SL_PARSE", s);
  424.         p -> trace = flag;
  425.         return;
  426.     }
  427.  
  428.     /* Search ALL hash lists. */
  429.     {
  430.         register int i;
  431.         for (i = 0; i < SL_MAX_HASH; i++) {
  432.  
  433.             for (p = sl_htab [i]; p; p = p -> next) {
  434.  
  435.                 /* Bug fix: 4/19/89 wildcards possible only in first arg. */
  436.                 if (sl_match(s, p -> name)) {
  437.  
  438.                     /* Set the wild bit only if p -> trace is not already on. */
  439.                     if (p -> trace) {
  440.                         p -> trace = flag;
  441.                     }
  442.                     else {
  443.                         p -> trace = flag ? (SL_TRACE_BIT | SL_WILD_BIT) : 0;
  444.                     }
  445.                 }
  446.             }
  447.         }
  448.     }
  449.  
  450.     /*
  451.         Add new element at the head of the wildcard list.
  452.         This will supercede any previous conflicting entries.
  453.     */
  454.     p      = sl_new(s);
  455.     p -> next  = sl_wcard;
  456.     sl_wcard   = p;
  457.     p -> trace = flag;
  458.     return;
  459. }
  460.  
  461. /*
  462.     Sign on.
  463. */
  464. void
  465. sl_signon(void)
  466. {
  467.     /* Sign on. */
  468.     es("Sherlock support routines: "); es(SL_VERSION_NAME); es(".\n");
  469.     signon_flag = TRUE;
  470. }
  471.  
  472. /*
  473.     Return TRUE if string s1 contains a wildcard character, i.e., an
  474.     asterisk or a question mark.
  475. */
  476. int
  477. sl_wild(register char *s)
  478. {
  479.     register char c;
  480.  
  481.     for (;;) {
  482.         c = *s++;
  483.         if (c == '\0') {
  484.             return FALSE;
  485.         }
  486.         else if (c == '*' || c == '?') {
  487.             return TRUE;
  488.         }
  489.     }
  490. }
  491.  
  492.